package Server;

import Strukture.Cvor;
import Strukture.ParLokMSek;
import Strukture.Stablo;
import java.io.File;
import java.util.LinkedList;

/**
 * Klasa koja sadrzi metode za kreiranje modela FileSystem-a i upravljanje njime
 * @author ivail
 */
public class FileSystem {
    
    
    /**
     * Staticka metoda koja pravi fizicki folder korisnika na lokaciji servera + ime korisnika
     * @author ivail
     * @param korisnik
     * @return da li je folder napravljen
     */
    static public boolean napraviFolderKorisnika (Korisnik korisnik){
        boolean vrati = (new File(ServerInfo.getLokacija()+korisnik.getIme())).mkdirs();
        return vrati;
    }
    
    /**
     * Pravi obican folder u okviru glavnog, korisnickog foldera
     * @author ivail
     * @param korisnik kod kojeg se pravi folder
     * @param putanja (relativna) samo u odnosu na korisnicki folder
     * @return da li je folder uspesno napravljen
     */
    static public boolean napraviFolderUKorisnickomFolderu (Korisnik korisnik, String putanja){
        boolean vrati = (new File(ServerInfo.getLokacija()+korisnik.getIme()+putanja)).mkdirs();
        return vrati;
    }
    
    /**
     * Metoda koja pravi cvor modela
     * @author ivail
     * @param nadredjeni cvor
     * @param ime cvora
     * @return novonapravljeni Cvor
     */
    
    static public Cvor napraviCvor (Cvor nadredjeni, String ime){
        Cvor novi = new Cvor (nadredjeni.getLokacija()+ime);
        return novi;
    }
    
    /**
     * pravljenje korenog cvora modela
     * @author ivail
     * @param korisnik ciji se cvor pravi
     * @return koreni cvor stabla
     */
    
    static public Cvor napraviKoreniCvor (Korisnik korisnik){
        Cvor koreni = new Cvor (ServerInfo.getLokacija()+korisnik.getIme());
        return koreni;
    }
    
    
    /**
     * Metoda koja na osnovu stanja foldera i fajlova na disku vraca model kao visegransko stablo; rekurzivna metoda koja se nadovezuje na 
     * @see Server.FileSystem#napraviStablo pogledaj
     * @author ivail
     * @param direktorijumi Prima spregnutu listu koja sadrzi objekte klase Cvor
     * @param korisnik korisnik za kojeg se radi (da bi se pristupilo odgovarajucim poljima)
     */
    
    static public void prolazIIspitivanje (LinkedList <Cvor> direktorijumi, Korisnik korisnik){
        if (!direktorijumi.isEmpty()){
        for (Cvor iter: direktorijumi){
            File folder2 = new File(iter.getLokacija());
            for (File unos: folder2.listFiles()){
                if (unos.isDirectory()){
                    iter.getDirektorijumi().add(new Cvor(unos.getAbsolutePath()));
                    korisnik.getListaLokacijaFoldera().add(unos.getAbsolutePath());
               }
                else {
                    iter.getFajlovi().add(unos.getAbsolutePath());
                    String lokacija = unos.getAbsolutePath();
                    long milisekunde = unos.lastModified();
                    korisnik.getListaLokacijaFajlova().add(FileSystem.vratiStringZaListu(lokacija, milisekunde));
                }
            }
            prolazIIspitivanje(iter.getDirektorijumi(), korisnik);   
        }
        }
    }
    
    /**
     * Metoda koja pravi stablo, zapravo je samo pocetak metode i poziva rekurzivnu; takodje dodaje lokacije u liste korisnika
     * @see Server.FileSystem#prolazIIspitivanje pogledaj
     * @see Klijent.Korisnik
     * @author ivail
     * @param koreni cvor
     * @param korisnik za kojeg se radi (da bi se pristupilo odgovarajucim poljima)
     * @return stablo
     */
    
    static public Stablo napraviStablo (Cvor koreni, Korisnik korisnik){
         
        Stablo stablo = new Stablo (koreni);
        
        File folder2 = new File (koreni.getLokacija());
        //System.out.println(koreni.getLokacija());
        for (File unos: folder2.listFiles()){
                if (unos.isDirectory()){
                    koreni.getDirektorijumi().add(new Cvor(unos.getAbsolutePath()));
                    korisnik.getListaLokacijaFoldera().add(unos.getAbsolutePath());
                }
                else {
                    koreni.getFajlovi().add(unos.getAbsolutePath());
                    String lokacija = unos.getAbsolutePath();
                    long milisekunde = unos.lastModified();
                    korisnik.getListaLokacijaFajlova().add(FileSystem.vratiStringZaListu(lokacija, milisekunde));
                }
            }
        
        prolazIIspitivanje(koreni.getDirektorijumi(), korisnik);
        return stablo;
 
    } 
//        predjasnja test metoda
//    public static void stampajStablo (Stablo stablo){
//        System.out.println(stablo.koren.getLokacija()+"\n");
//        
//        LinkedList <Cvor> vrteska = new LinkedList <Cvor> ();
//        vrteska.add(stablo.koren);
//        while (!vrteska.equals(null)){
//            for (Cvor iter: vrteska){
//                System.out.println(iter.getLokacija()+"\n");
//                vrteska = iter.getDirektorijumi();
//            }
//
//        }
//        
//        
//        
//        String stampa = "";
//        for (Cvor proba: stablo.koren.getDirektorijumi()){
//            stampa = stampa+"\n"+proba.getLokacija();
//        }
//        
//        String stampa2 = "";
//        for (String proba: stablo.koren.getFajlovi()){
//            stampa = stampa+"\n"+proba;
//        }       
//        System.out.println(stablo.koren+"\n"+stampa+"\n"+stampa2);
//    }
//    
    

    /**
     * Proverava staticko polje u klasi UlogovaniKorisnik i ako je prazno, korisnik jos nije ulogovan
     * @author ivail
     * @return da li je korisnik ulogovan
     * @see UlogovaniKorisnik
     */

    static public boolean proveriDaLiJeKorisnikUlogovan (){
        if (Klijent.UlogovaniKorisnik.getImeKorisnika().equalsIgnoreCase(null)){
            return false;
        } else return true;
    }


    /**
     * Vraca objekat ulogovanog korisnika
     * @author ivail
     * @return objekat ulogovanog korisnika
     */
    static public Korisnik napraviUlogovanogKorisnika (){
        return new Korisnik (Klijent.UlogovaniKorisnik.getImeKorisnika(), Klijent.UlogovaniKorisnik.getSifraKorisnika());
    }

    /**
     * Vraca relativnu putanju
     * @author ivail
     * @param seci duzi string
     * @param lokacija kraci string
     * @return relativna putanja
     */
    
    static public String vratiRelativnuPutanju (String seci, String lokacija){

        return new File(lokacija).toURI().relativize(new File(seci).toURI()).getPath();

    }
    
    /**
     * Vraca Lokacija+@@@@@+milisekunde
     * @author ivail
     * @param lokacija fajla
     * @param milisekunde starost fajla
     * @return Lokacija+@@@@@+milisekunde
     */
    
    static public String vratiStringZaListu (String lokacija, long milisekunde){
        return lokacija+"@@@@@"+milisekunde;
    }
    
    /**
     * Vraca objekat navedene klase koji sadrzi odvojene lokacije i milisekunde
     * @param seci
     * @author ivail
     * @return objekat klase, pogledaj:
     * @see Strukture.ParLokMSek
     */
    static public ParLokMSek vratiStringIzListeUNormalan (String seci){
        String [] delovi = seci.split("@@@@@");

        return new ParLokMSek(delovi[0], Long.parseLong(delovi[1]));

    }
            
     
    /**
     * Proverava da li korisnik koristeci klijentski program sinhronizuje fajlove
     * @param k korisnik
     * @author ivail
     * @return boolean da li ili ne
     */
    static public boolean proveriDaLiSeSinhronizuje (Korisnik k){
        return ServerInfo.getAktivnoSinhronizuju().contains(k.getIme());
    }
            
    
    /**
     * Brise korisnika iz liste onih koji se aktivno sinhronizuju
     * @author ivail
     * @param k 
     */
    static public void izbaciIzListeOnihKojiSeSinhronizuju (Korisnik k){
        ServerInfo.getAktivnoSinhronizuju().remove(k.getIme());
    }
}
